# encoding=utf-8

from threading import Lock
from sdktest_module.utils import adbCommand
from sdktest_module.utils.constant import *
import json

class Device:
    def __init__(self, device_id, client_port, platform=ANDROID, is_cloud_device=False, wda_url=None, rpc=None,
                 brand=None, model=None, serial=None, osVersion=None):
        self.device_id = device_id
        self.client_port = client_port
        self.platform = platform
        self.wda_url = wda_url
        self.rpc = rpc
        self.is_cloud_device = is_cloud_device
        self.brand = brand
        self.model = model
        self.serial = serial
        self.os_version = osVersion

    def __hash__(self):
        return hash(self.device_id)

    def __eq__(self, other):
        if isinstance(other, self.__class__):
            return self.device_id == other.device_id
        else:
            return False

    def __str__(self):
        if self.platform == ANDROID:
            return "device{{id:{}, port:{}, brand:{}, model:{}, serial:{}}}".format(
                self.device_id, self.client_port, self.brand, self.model, self.serial)
        else:
            return "device{{id:{}, port:{}, wda_url:{}, model:{}, serial:{}}}".format(
                self.device_id, self.client_port, self.wda_url, self.model, self.serial)


class DeviceManger:
    def __init__(self):
        self._online_devices = []
        self._lock = Lock()

    def parse_cloud_devices(self, clound_device):
        devices_info = []
        try:
            devices_info = json.loads(clound_device)
        except json.JSONDecodeError:
            print('解析云手机异常')
        return devices_info
    def init_devices(self, client_port, cloud_device_json_string=None):
        """
        更新在线设备列表
        server_port: tcp server 端口
        is_local_debug:本地开发模式
        clound_devices: --devices 传过来的云平台真机

        android手机，本地和云真机逻辑类似，分配rpc端口，adb forward端口映射
        ios手机，1.本地手机需要自己分配wda和rpc端口，并iproxy实现映射，云真机使用平台提供的wda和rpc端口
        云手机格式[{device_id:127.0.0.1:20000,platform:android},{device_id:xxx,platform:ios,wda_url:http://127.0.0.1:9000,rpc:127.0.0.1:20010}]
        """
        self._online_devices.clear()
        #分别获取android和iOS本地设备
        online_android_devices = adbCommand.checkCellOnline()
        online_ios_devices = adbCommand.checkCellOnlineIos()
        assert len(online_android_devices) >= 0 or len(online_ios_devices) >= 0 or cloud_device_json_string is not None, "没有本地手机和云手机"

        if not cloud_device_json_string:
            # 添加本地的在线设备
            [self._insert_device(Device(device_id, client_port + i, platform=ANDROID)) for i, device_id in
             enumerate(online_android_devices)]
            ios_start_port = client_port + len(online_android_devices)
            #ios需要2个端口
            [self._insert_device(Device(device_id, ios_start_port + i*2, platform=IOS)) for i, device_id in
             enumerate(online_ios_devices)]
            #调试模式只用本地手机
            return
        if cloud_device_json_string:
            # 添加在线的云真机
            cloud_devices = self.parse_cloud_devices(cloud_device_json_string)
            if len(cloud_devices) > 0:
                for cloud_device in cloud_devices:
                    if cloud_device['platform'] == ANDROID:
                        if cloud_device['device_id'] in online_android_devices:
                            self._insert_device(Device(cloud_device['device_id'], client_port, platform=ANDROID,
                                                       brand=cloud_device['brand'], model=cloud_device['model'],
                                                       serial=cloud_device['serial'],
                                                       osVersion=cloud_device['osVersion']))
                            client_port = client_port + 1
                    if cloud_device['platform'] == IOS:
                        self._insert_device(Device(cloud_device['device_id'], client_port,
                                                   is_cloud_device=True, platform=IOS,
                                                   wda_url=cloud_device['wdaUrl'], rpc=cloud_device['rpcUrl'],
                                                   brand=cloud_device['brand'], model=cloud_device['model'],
                                                   serial=cloud_device['serial'], osVersion=cloud_device['osVersion']))
                        client_port = client_port + 2
            # online_clound_device = [device_id for device_id in online_android_devices if device_id in cloud_device_json_string]
            # [self._insert_device(Device(device_id, client_port + i)) for i, device_id in
            #  enumerate(online_clound_device)]
    def _insert_device(self, device):
        """
        去重后，插入列表
        """
        if device not in self._online_devices: # 去重
            self._online_devices.append(device)

    def device_info(self):
        """
        打印设备信息
        """
        return str(list(map(str, self._online_devices)))

    def get_devices(self, num):
        """
        获取指定数量的设备
        """
        try:
            self._lock.acquire()
            # assert len(self._online_devices)>=num, "在线设备数:{} <  用例申请数:{}".format(len(self._online_devices, num))
            online_num = len(self._online_devices)
            if online_num == 0:
                return []
            elif online_num < num:
                return self._online_devices[0:online_num]
            else:
                return self._online_devices[0:num]

        finally:
            self._lock.release()

    def  get_device_num(self):
        return len(self._online_devices)


if __name__ == "__main__":
    mgr = DeviceManger()
    mgr.init_online_devices(9000, False, ["123", "345", "123", "345"])
    print("RC:{}".format(mgr.device_info()))
